"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHookData = exports.getPort = exports.getHttpQuery = exports.getHttpBody = exports.notFound = void 0;
const tslib_1 = require("tslib");
const qs = tslib_1.__importStar(require("querystring"));
const URL = tslib_1.__importStar(require("url"));
const get_port_1 = tslib_1.__importDefault(require("get-port"));
const sign_1 = tslib_1.__importDefault(require("./sign"));
const utils_1 = require("./utils");
function notFound(res, message) {
    res.statusCode = 404;
    const body = ['404'];
    if (message)
        body.push(message);
    res.end(body.join(', '));
}
exports.notFound = notFound;
/**
 * 获取post请求的body
 */
async function getHttpBody(req, secret = '') {
    return new Promise((resolve, reject) => {
        let data = '';
        req.on('data', chunk => {
            data += chunk;
        });
        req.on('end', () => {
            try {
                const valid = sign_1.default(req, secret, data);
                const contentType = req.headers['content-type'];
                if (contentType === 'application/json') {
                    resolve({ body: JSON.parse(data), valid });
                }
                else if (contentType === 'application/x-www-form-urlencoded') {
                    let body = qs.parse(data);
                    if (body.payload) {
                        body = JSON.parse(typeof body.payload === 'string' ? body.payload : '');
                    }
                    resolve({ body, valid });
                }
                else {
                    resolve({ body: data, valid });
                }
            }
            catch (err) {
                reject(err);
            }
        });
        req.on('error', (err) => {
            reject(err);
        });
    });
}
exports.getHttpBody = getHttpBody;
/**
 * 获取url中的参数
 */
function getHttpQuery(req) {
    const urlObj = URL.parse(req.url || '{}');
    const query = urlObj.query ? qs.parse(urlObj.query) : {};
    return query;
}
exports.getHttpQuery = getHttpQuery;
/**
 * 获取端口，如果未提供port参数则随机从8000-8100中选择
 */
async function getPort(port) {
    if (port !== undefined && /^\d+$/.test(String(port))) {
        const p = await get_port_1.default({ port: Number(port) });
        if (p !== Number(port)) {
            await utils_1.logError('', 'start', `${port} 端口已被占用`);
            process.exit(1);
        }
        return p;
    }
    return await get_port_1.default({ port: get_port_1.default.makeRange(8000, 8100) });
}
exports.getPort = getPort;
async function returnHookData(req, secret, conditionHandler) {
    const result = await getHttpBody(req, secret);
    if (result.valid && conditionHandler(result.body)) {
        return { status: true, body: result.body };
    }
    return { status: false };
}
/**
 * 判断是否是添加标签事件，并返回body
 */
async function getHookData(req, secret = '') {
    const reg1 = /^refs\/tags\/v(\d+\.)*\d+$/;
    const reg2 = /^v(\d+\.)*\d+$/;
    const giteeEvent = req.headers['x-gitee-event'];
    const githubEvent = req.headers['x-github-event'];
    const gitlabEvent = req.headers['x-gitlab-event'];
    if (giteeEvent) {
        if (giteeEvent === 'Tag Push Hook') {
            // created为true时为创建
            return await returnHookData(req, secret, (body) => body.created && reg1.test(body.ref));
        }
    }
    else if (githubEvent) {
        if (githubEvent === 'create') {
            // 创建分支和添加tag都是create事件； 删除tag是push事件；
            return await returnHookData(req, secret, (body) => body.ref_type === 'tag' && reg2.test(body.ref));
        }
    }
    else if (gitlabEvent) {
        if (gitlabEvent === 'Tag Push Hook') {
            // 添加和删除tag都是`Tag Push Hook`事件；添加tag时commits为非空数组；
            return await returnHookData(req, secret, (body) => body.commits.length > 0 && reg1.test(body.ref));
        }
    }
    else {
        for (const key in req.headers) {
            if (/^x-[\w-]+-event$/i.test(key)) {
                const eventName = req.headers[key];
                if (typeof eventName === 'string' && eventName === 'push') {
                    return await returnHookData(req, secret, (body) => reg1.test(body.ref));
                }
            }
        }
    }
    return { status: false };
}
exports.getHookData = getHookData;
